/**
 * @file ble_key.cpp
 * @brief
 * @author  xiaowine (xiaowine@sina.cn)
 * @version 01.00
 * @date    2021-01-16
 *
 * @copyright Copyright (c) {2020}  xiaowine
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2021-01-16 <td>1.0     <td>wangh     <td>内容
 * </table>
 * ******************************************************************
 * *                   .::::
 * *                 .::::::::
 * *                ::::::::::
 * *             ..:::::::::::
 * *          '::::::::::::
 * *            .:::::::::
 * *       '::::::::::::::..        女神助攻,流量冲天
 * *            ..::::::::::::.     永不宕机,代码无bug
 * *          ``:::::::::::::::
 * *           ::::``:::::::::'        .:::
 * *          ::::'   ':::::'       .::::::::
 * *        .::::'      ::::     .:::::::'::::
 * *       .:::'       :::::  .:::::::::' ':::::
 * *      .::'        :::::.:::::::::'      ':::::
 * *     .::'         ::::::::::::::'         ``::::
 * * ...:::           ::::::::::::'              ``::
 * *```` ':.          ':::::::::'                  ::::.
 * *                   '.:::::'                    ':'````.
 * ******************************************************************
 */

#include <rtthread.h>
#include "thread_entries.h"
#include <rtdevice.h>
#include "ble_key.h"
#include "i2c_utils.h"
#include "mb_event_cpad.h"
#include "sys_status.h"
#include "req_execution.h"
#include "local_status.h"
#include "global_var.h"
/*************************define**log****************************************************/
#define CONFIG_DEBUG
#ifdef CONFIG_DEBUG
#ifndef bleKeyLog
#define bleKeyLog(N, ...) rt_kprintf("[%d][bleKey:%04d]" N "\r\n", rt_tick_get(), __LINE__, ##__VA_ARGS__)
#endif /* bleKeyLog(...) */
#else
#define bleKeyLog(...)
#endif /* ! CONFIG_DEBUG */
/*************************I2C******************************************************/
#define I2C_ADDRESS 0x7e
#ifdef I2C_TOOLS_USE_SW_I2C
#define SDA_PORT_NUM 61
#define SCL_PORT_NUM 62
#else
#define I2C_DEVICE_NAME "i2c1"
#endif

#define BUFFMAX 22

static rt_uint8_t tx_buffer[BUFFMAX] = {1, 2, 3, 4, 5, 0, 7, 8, 9, 20};
static rt_uint8_t rx_buffer[BUFFMAX] = {20, 9, 8, 7, 6, 5, 4, 3, 2, 1};
const rt_uint8_t protocolHeader[2]   = {0xff, 0xa5};

#define PARA_ADDR_START 64
#define PARA_NUM 22
#define STATE_ADDR_START 500
#define STATE_NUM 8

static rt_uint8_t regMap[PARA_NUM + STATE_NUM][14] = {0};

static rt_uint16_t segmentValue[3]    = {0};
static rt_uint16_t segmentValueBak[3] = {0xffff};

rgbLevel_t levelRGB    = {0};
rgbLevel_t levelRGBBak = {0};
#define HOT_RGB_WATER_SRC levelRGB.color[0]
#define HOT_RGB_WATER_OUT levelRGB.color[1]
#define HOT_RGB_WATER_HEA levelRGB.color[2]

#define COLD_RGB_WATER_OUT levelRGB.color[0]
#define COLD_RGB_FILTER levelRGB.color[1]
#define COLD_RGB_ELEMENT levelRGB.color[2]

/*******************************************************************************/
extern local_reg_st l_sys;
extern sys_reg_st g_sys;
/*************************Variable declaration******************************************************/
_TKS_FLAGA_type bleKeyFlag = {0};
#define PARACHANGEFLAG bleKeyFlag.bits.b0
#define DOUBLE_CLICK_FLAG bleKeyFlag.bits.b1

_TKS_FLAGA_type keyState[KEYBYTENUM];
_TKS_FLAGA_type keyUpState[KEYBYTENUM];
volatile _TKS_FLAGA_type keyTrg[KEYBYTENUM];
volatile _TKS_FLAGA_type keyUpTrg[KEYBYTENUM];

#define SHOTBEEPMASK 0x07
#define LONGBEEPMASK 0x07
rt_uint8_t keyBeepMask[2]    = {SHOTBEEPMASK, LONGBEEPMASK};
rt_uint8_t keyBeepMaskBak[2] = {0};

_USR_FLAGA_type ledState[2];

_BEEP_STATE beepState     = {0, 0, 0};
rt_uint8_t beepShortCount = 0;
rt_uint8_t beepLongCount  = 0;
/****************************************************************************/
rt_uint8_t getCheckSum(rt_uint8_t *data);
void keyRecOperation(_TKS_FLAGA_type *keyState);
void operateRxData(rt_uint8_t *rxData);
rt_uint8_t *getRegData(void);
static void caculateLed(void);
static void waterOutOpt(uint8_t outWaterval);

rt_tick_t pressT        = 0;
rt_tick_t rangTimeFlash = 0;
rt_tick_t longPressT    = 0;
#define DOUBLE_CLICK_THRESHOLD 2000  // 2S
#define TICKS_OF_5S 5000             // 2S
#define LONG_PRESS_THRESHOLD 6000    // 2S
/****************************************************************************/

void keyRecOperation(_TKS_FLAGA_type *keyState)
{
    static rt_uint8_t k_count[KEYBYTENUM]   = {0};
    static rt_uint8_t k_Upcount[KEYBYTENUM] = {0};

    for (rt_uint8_t i = 0; i < KEYBYTENUM; i++)
    {
        keyTrg[i].byte = (keyState + i)->byte & ((keyState + i)->byte ^ k_count[i]);
        k_count[i]     = (keyState + i)->byte;
    }

    for (rt_uint8_t i = 0; i < KEYBYTENUM; i++)
    {
        keyUpState[i].byte = ~(keyState + i)->byte;
        keyUpTrg[i].byte   = keyUpState[i].byte & (keyUpState[i].byte ^ k_Upcount[i]);
        k_Upcount[i]       = keyUpState[i].byte;
    }
    if (g_sys.status.ComSta.u16edition == HOT_COLD_EDITION)
        goto coldEdition;

    if (hotWaterOutKeyTrg)
    {
        bleKeyLog("hotWaterOutKeyTrg");
        if (l_sys.OutWater_Flag != WATER_NO)
            waterOutOpt(FALSE);
    }
    if (hotWaterScrKeyTrg)
    {
        // bleKeyLog("hotWaterScrKeyTrg");
    }

    if (hotHeatKeyTrg)
    {
        if (l_sys.LedKey.heateSwitch)
            l_sys.LedKey.heateSwitch = 0;
        bleKeyLog("hotHeatKeyTrg");
    }

    if (hotWaterOutUpKeyTrg)
    {
    }
    if (hotHeatUpKeyTrg)
    {
    }
    if (hotWaterScrUpKeyTrg)
    {
        if ((rt_tick_get() - pressT) < DOUBLE_CLICK_THRESHOLD)
        {
            pressT            = 0;
            DOUBLE_CLICK_FLAG = 1;
            rangTimeFlash     = rt_tick_get();
            bleKeyLog("waterScrUpKeyTrg double click");
        }
        else
        {
            pressT = rt_tick_get();
        }
    }

    if (hotWaterOutKeyRestainTrg)
    {
        if (hotHeatKey || hotWaterScrKey)
        {
        }
        else
        {
            bleKeyLog("hotWaterOutKeyRestainTrg");
            if (l_sys.OutWater_Flag == WATER_NO)
                waterOutOpt(TRUE);
        }
    }
    if (hotHeatKeyRestainTrg)
    {
        if (hotWaterScrKey || hotWaterOutKey)
        {
        }
        else
        {
            if ((g_sys.status.ComSta.u16Ain[AI_NTC3] < g_sys.config.ComPara.u16HotWater_Temp) &&
                (get_alarm_bitmap(ACL_NTC3) == 0))
                l_sys.LedKey.heateSwitch = 1;
            bleKeyLog("hotHeatKeyRestainTrg");
        }
    }

    if (hotWaterScrKeyRestainTrg)
    {
        if (hotHeatKey || hotWaterOutKey)
        {
        }
        else
        {
            if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_AIR)
            {
                g_sys.config.ComPara.u16ExitWater_Mode = WATER_FILL;
            }
            else if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_FILL)
            {
                g_sys.config.ComPara.u16ExitWater_Mode = WATER_AIR;
            }
            bleKeyLog("hotWaterScrKeyRestainTrg");
        }
    }
    if (hotWaterScrKey && (hotHeatKey || hotWaterOutKey))
    {
        if ((rt_tick_get() - longPressT) < TICKS_OF_5S)
        {
        }
        else if ((rt_tick_get() - longPressT) < LONG_PRESS_THRESHOLD)
        {
            longPressT = 0;
            if (hotWaterScrKey && hotWaterOutKey)
            {
                bleKeyLog("hotWaterScrKey && hotWaterOutKey longPress");
                reset_runtime(DO_FILLTER_DUMMY_BPOS);
            }
            else if (hotWaterScrKey && hotHeatKey)
            {
                bleKeyLog("hotWaterScrKey && hotHeatKey longPress");
                reset_runtime(DO_FILLTER_ELEMENT_DUMMY_BPOS_0);
                reset_runtime(DO_FILLTER_ELEMENT_DUMMY_BPOS_1);
            }
        }
    }
    else
    {
        longPressT = rt_tick_get();
    }

    goto exit_key;
coldEdition:
    if (coldElementKeyTrg)
    {
        bleKeyLog("coldElementKeyTrg");
    }
    if (coldFilterKeyTrg)
    {
        // bleKeyLog("coldFilterKeyTrg");
    }
    if (coldWaterOutKeyTrg)
    {
        bleKeyLog("coldWaterOutKeyTrg");
        if (l_sys.OutWater_Flag != WATER_NO)
            waterOutOpt(FALSE);
    }

    if (coldFilterUpKeyTrg)
    {
    }
    if (coldElementUpKeyTrg)
    {
    }
    if (coldWaterOutUpKeyTrg)
    {
        if ((rt_tick_get() - pressT) < DOUBLE_CLICK_THRESHOLD)
        {
            pressT            = 0;
            DOUBLE_CLICK_FLAG = 1;
            rangTimeFlash     = rt_tick_get();
            bleKeyLog("waterOutUpKeyTrg double click");
        }
        else
        {
            pressT = rt_tick_get();
        }
    }

    if (coldFilterKeyRestainTrg)
    {
        // bleKeyLog("coldFilterKeyRestainTrg");
    }
    if (coldElementKeyRestainTrg)
    {
        // bleKeyLog("coldElementKeyRestainTrg");
    }

    if (coldWaterOutKeyRestainTrg)
    {
        if (coldFilterKey || coldElementKey)
        {
        }
        else
        {
            bleKeyLog("coldWaterOutKeyRestainTrg");
            if (l_sys.OutWater_Flag == WATER_NO)
                waterOutOpt(TRUE);
        }
    }

    if ((coldFilterKey && coldElementKey && (!coldWaterOutKey)) ||
        (coldFilterKey && (!coldElementKey) && coldWaterOutKey) ||
        ((!coldFilterKey) && coldElementKey && coldWaterOutKey))
    {
        if ((rt_tick_get() - longPressT) < TICKS_OF_5S)
        {
        }
        else if ((rt_tick_get() - longPressT) < LONG_PRESS_THRESHOLD)
        {
            longPressT = 0;
            if (coldFilterKey && coldElementKey)
            {
                bleKeyLog("coldFilterKey && coldElementKey longPress");
                if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_AIR)
                {
                    g_sys.config.ComPara.u16ExitWater_Mode = WATER_FILL;
                }
                else if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_FILL)
                {
                    g_sys.config.ComPara.u16ExitWater_Mode = WATER_AIR;
                }
            }
            else if (coldFilterKey && coldWaterOutKey)
            {
                bleKeyLog("coldFilterKey && coldWaterOutKey longPress");
                reset_runtime(DO_FILLTER_DUMMY_BPOS);
            }
            else if (coldElementKey && coldWaterOutKey)
            {
                bleKeyLog("coldElementKey && coldWaterOutKey longPress");
                reset_runtime(DO_FILLTER_ELEMENT_DUMMY_BPOS_0);
                reset_runtime(DO_FILLTER_ELEMENT_DUMMY_BPOS_1);
            }
        }
    }
    else
    {
        longPressT = rt_tick_get();
    }
exit_key:

    if (BLEON)
    {
    }
    if (BLEONTrg)
    {
        rt_memset(regMap, 0, sizeof(regMap));
        bleKeyLog("BLEON");
    }
    if (BLEINITDONE)
    {
    }
    if (BLEINITDONETrg)
    {
        bleKeyLog("BLEINITDONETrg");
    }
}
void operateRxData(rt_uint8_t *rxData)
{
    if ((*(rxData + 3) + 5) > BUFFMAX)
    {
        return;
    }
    if (rt_memcmp(protocolHeader, rxData, 2) != 0)
    {
        return;
    }

    if (getCheckSum(rxData) == *(rxData + *(rxData + 3) + 4))
    {
        switch (*(rxData + 2))
        {
            case CMD_IDEL:
                break;
            case CMD_KEY: {
                keyState[0].byte = *(rxData + 4);
                keyState[1].byte = *(rxData + 5);
                keyState[2].byte = *(rxData + 6);
                keyRecOperation(keyState);
                break;
            }
            case CMD_LED:
                break;
            case CMD_REG_UP:
                rt_kprintf("i2c_read I2C_REG_UP \n");
                break;
            case CMD_REG_DOWN: {
                rt_uint8_t length = *(rxData + 3) - 2;
                rt_uint8_t row, index;
                rt_uint16_t address = (*(rxData + 4) << 8) + *(rxData + 5);
                rt_kprintf("length:%d address:%d \n", length, address);
                cpad_eMBRegHoldingCB(rxData + 6, address, length / 2, CPAD_MB_REG_MULTIPLE_WRITE);
                if (address > STATE_ADDR_START)
                {
                    row = (address - STATE_ADDR_START) / 6 + PARA_NUM;
                }
                else
                {
                    row = (address - PARA_ADDR_START) / 6;
                }
                index = ((address - PARA_ADDR_START) % 6) * 2;

                rt_kprintf("((length > (12 - index)) ? (12 - index) : length):%d row:%d \n",
                           (length > (12 - index)) ? (12 - index) : length, row);
                rt_memcpy(&regMap[row][index + 2], rxData + 6, (length > (12 - index)) ? (12 - index) : length);
                if ((12 - index) < length)
                {
                    row++;
                    rt_kprintf("(length + index - 12):%d row:%d \n", length + index - 12, row);
                    rt_memcpy(&regMap[row][2], rxData + 12 - index, length + index - 12);
                }
                break;
            }
            case CMD_AUX_DIAI:
                break;
            case CMD_AUX_DO:
                break;
            case CMD_PARA:
                break;
            default:
                break;
        }
    }
    else
    {
        for (char i = 0; i < 20; i++)
        {
            rt_kprintf("%02x ", *(rxData + i));
        }
        rt_kprintf("\r\n");
        rt_kprintf("***checkSum err \n");
    }
}

rt_uint8_t getCheckSum(rt_uint8_t *data)
{
    rt_uint8_t checkSum = 0;
    if ((*(data + 3) + 4) > (BUFFMAX - 1))
    {
        return 0;
    }
    for (rt_uint8_t i = 0; i < (*(data + 3) + 4); i++)
    {
        checkSum += *(data + i);
    }
    return checkSum;
}

rt_uint8_t *getRegData(void)
{
    rt_uint8_t temp[12];
    for (rt_uint8_t i = 0; i < 30; i++)
    {
        rt_uint16_t address = (i < PARA_NUM) ? (i * 6 + PARA_ADDR_START) : ((i - PARA_NUM) * 6 + STATE_ADDR_START);
        cpad_eMBRegHoldingCB(temp, address, 6, CPAD_MB_REG_READ);
        if (rt_memcmp(&regMap[i][2], temp, 12) != 0)
        {
            regMap[i][0] = (address >> 8);
            regMap[i][1] = address & 0xff;
            rt_memcpy(&regMap[i][2], temp, 12);
            rt_kprintf("index:%04d\n", address - ((i < PARA_NUM) ? PARA_ADDR_START : 0));
            return &regMap[i][0];
        }
    }
    return RT_NULL;
}

static void caculateLed(void)
{
    levelRGB.level = g_sys.status.ComSta.u16waterVolume / 450;
    if (g_sys.status.ComSta.u16edition == HOT_COLD_EDITION)
        goto coldEdition;
    if (DOUBLE_CLICK_FLAG)
    {
        if ((g_sys.status.ComSta.u16Ain[AI_NTC1] < g_sys.config.ComPara.u16Start_Temp[0]) ||
            (g_sys.status.ComSta.u16Ain[AI_NTC1] > g_sys.config.ComPara.u16Stop_Temp[1]))
        {
            if ((rt_tick_get() - rangTimeFlash) > TICKS_OF_5S)
            {
                DOUBLE_CLICK_FLAG = 0;
            }
            else
            {
                HOT_RGB_WATER_SRC.blue  = 50;
                HOT_RGB_WATER_SRC.green = 50;
                HOT_RGB_WATER_SRC.red   = 50;
                HOT_RGB_WATER_OUT.red   = 50;
                HOT_RGB_WATER_OUT.green = 50;
                HOT_RGB_WATER_OUT.blue  = 50;
                HOT_RGB_WATER_HEA.red   = 50;
                HOT_RGB_WATER_HEA.green = 50;
                HOT_RGB_WATER_HEA.blue  = 50;
                hotWaterSrcLedState     = STATE_LED_FLASH_1HZ;
                hotWaterOutLedState     = STATE_LED_FLASH_1HZ;
                hotHeaterLedState       = STATE_LED_FLASH_1HZ;
            }
        }
        else
        {
            DOUBLE_CLICK_FLAG = 0;
        }
    }
    else
    {
        if ((g_sys.status.alarm_bitmap[0] & 0x1fff) || (g_sys.status.alarm_bitmap[1] & 0xfff8))
        {
            hotWaterSrcLedState = STATE_LED_FLASH_1HZ;
            hotWaterOutLedState = STATE_LED_FLASH_1HZ;
            hotHeaterLedState   = STATE_LED_FLASH_1HZ;
            if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_AIR)
            {
                HOT_RGB_WATER_SRC.blue  = 50;
                HOT_RGB_WATER_SRC.green = 50;
                HOT_RGB_WATER_SRC.red   = 50;
            }
            else
            {
                HOT_RGB_WATER_SRC.blue  = 0;
                HOT_RGB_WATER_SRC.green = 50;
                HOT_RGB_WATER_SRC.red   = 0;
            }
            HOT_RGB_WATER_HEA.blue  = 0;
            HOT_RGB_WATER_HEA.green = 0;
            HOT_RGB_WATER_HEA.red   = 50;

            HOT_RGB_WATER_OUT.blue  = 50;
            HOT_RGB_WATER_OUT.green = 0;
            HOT_RGB_WATER_OUT.red   = 0;
        }
        else
        {
            if (get_alarm_bitmap(ACL_FILTER_ELEMENT_0_OT) || get_alarm_bitmap(ACL_FILTER_ELEMENT_1_OT) ||
                get_alarm_bitmap(ACL_FILTER_ELEMENT_2_OT) || get_alarm_bitmap(ACL_FILTER_ELEMENT_3_OT) ||
                get_alarm_bitmap(ACL_FILTER_ELEMENT_4_OT))
            {
                hotWaterSrcLedState     = STATE_LED_ON;
                HOT_RGB_WATER_SRC.blue  = 0;
                HOT_RGB_WATER_SRC.green = 0;
                HOT_RGB_WATER_SRC.red   = 50;
            }
            else if (get_alarm_bitmap(ACL_FILTER_OT))
            {
                hotWaterSrcLedState     = STATE_LED_FLASH_1HZ;
                HOT_RGB_WATER_SRC.blue  = 0;
                HOT_RGB_WATER_SRC.green = 0;
                HOT_RGB_WATER_SRC.red   = 50;
            }
            else
            {
                if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_AIR)
                {
                    HOT_RGB_WATER_SRC.blue  = 50;
                    HOT_RGB_WATER_SRC.green = 50;
                    HOT_RGB_WATER_SRC.red   = 50;
                }
                else
                {
                    HOT_RGB_WATER_SRC.blue  = 0;
                    HOT_RGB_WATER_SRC.green = 50;
                    HOT_RGB_WATER_SRC.red   = 0;
                }
                if (l_sys.Cold_Water)
                {
                    hotWaterSrcLedState = STATE_LED_FLASH_1HZ;
                }
                else
                {
                    hotWaterSrcLedState = STATE_LED_ON;
                }
            }
            if (l_sys.LedKey.heateSwitch)
            {
                hotHeaterLedState = STATE_LED_ON;
            }
            else
            {
                hotHeaterLedState = STATE_LED_OFF;
            }
            HOT_RGB_WATER_HEA.blue  = 0;
            HOT_RGB_WATER_HEA.green = 0;
            HOT_RGB_WATER_HEA.red   = 50;
            if (l_sys.OutWater_Flag != WATER_NO)
            {
                hotWaterOutLedState = STATE_LED_ON;
            }
            else
            {
                hotWaterOutLedState = STATE_LED_OFF;
            }
            HOT_RGB_WATER_OUT.blue  = 50;
            HOT_RGB_WATER_OUT.green = 0;
            HOT_RGB_WATER_OUT.red   = 0;
        }
    }
    goto exitCaculate;
coldEdition:
    if (DOUBLE_CLICK_FLAG)
    {
        if ((g_sys.status.ComSta.u16Ain[AI_NTC1] < g_sys.config.ComPara.u16Start_Temp[0]) ||
            (g_sys.status.ComSta.u16Ain[AI_NTC1] > g_sys.config.ComPara.u16Stop_Temp[1]))
        {
            if ((rt_tick_get() - rangTimeFlash) > TICKS_OF_5S)
            {
                DOUBLE_CLICK_FLAG = 0;
            }

            COLD_RGB_WATER_OUT.blue  = 50;
            COLD_RGB_WATER_OUT.green = 50;
            COLD_RGB_WATER_OUT.red   = 50;
            COLD_RGB_FILTER.red      = 50;
            COLD_RGB_FILTER.green    = 50;
            COLD_RGB_FILTER.blue     = 50;
            COLD_RGB_ELEMENT.red     = 50;
            COLD_RGB_ELEMENT.green   = 50;
            COLD_RGB_ELEMENT.blue    = 50;
            coldWaterOutLedState     = STATE_LED_FLASH_1HZ;
            coldFilterLedState       = STATE_LED_FLASH_1HZ;
            coldElementLedState      = STATE_LED_FLASH_1HZ;
        }
        else
        {
            DOUBLE_CLICK_FLAG = 0;
        }
    }
    else
    {
        if ((g_sys.status.alarm_bitmap[0] & 0x1fff) || (g_sys.status.alarm_bitmap[1] & 0xfff8))
        {
            coldWaterOutLedState = STATE_LED_FLASH_1HZ;
            coldFilterLedState   = STATE_LED_FLASH_1HZ;
            coldElementLedState  = STATE_LED_FLASH_1HZ;
            if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_AIR)
            {
                COLD_RGB_WATER_OUT.blue  = 50;
                COLD_RGB_WATER_OUT.green = 50;
                COLD_RGB_WATER_OUT.red   = 50;
            }
            else
            {
                COLD_RGB_WATER_OUT.green = 50;
                COLD_RGB_WATER_OUT.red   = 0;
                COLD_RGB_WATER_OUT.blue  = 0;
            }
        }
        else
        {
            if (get_alarm_bitmap(ACL_FILTER_ELEMENT_0_OT) || get_alarm_bitmap(ACL_FILTER_ELEMENT_1_OT) ||
                get_alarm_bitmap(ACL_FILTER_ELEMENT_2_OT) || get_alarm_bitmap(ACL_FILTER_ELEMENT_3_OT) ||
                get_alarm_bitmap(ACL_FILTER_ELEMENT_4_OT))
            {
                coldElementLedState    = STATE_LED_ON;
                COLD_RGB_ELEMENT.blue  = 0;
                COLD_RGB_ELEMENT.green = 0;
                COLD_RGB_ELEMENT.red   = 50;
            }
            else
            {
                coldElementLedState    = STATE_LED_ON;
                COLD_RGB_ELEMENT.blue  = 50;
                COLD_RGB_ELEMENT.green = 50;
                COLD_RGB_ELEMENT.red   = 50;
            }

            if (get_alarm_bitmap(ACL_FILTER_OT))
            {
                coldFilterLedState    = STATE_LED_ON;
                COLD_RGB_FILTER.blue  = 0;
                COLD_RGB_FILTER.green = 0;
                COLD_RGB_FILTER.red   = 50;
            }
            else
            {
                coldFilterLedState    = STATE_LED_ON;
                COLD_RGB_FILTER.blue  = 50;
                COLD_RGB_FILTER.green = 50;
                COLD_RGB_FILTER.red   = 50;
            }
            if (g_sys.config.ComPara.u16ExitWater_Mode == WATER_AIR)
            {
                COLD_RGB_WATER_OUT.blue  = 50;
                COLD_RGB_WATER_OUT.green = 50;
                COLD_RGB_WATER_OUT.red   = 50;
            }
            else
            {
                COLD_RGB_WATER_OUT.green = 50;
                COLD_RGB_WATER_OUT.red   = 0;
                COLD_RGB_WATER_OUT.blue  = 0;
            }
            if (l_sys.Cold_Water)
            {
                coldWaterOutLedState = STATE_LED_FLASH_1HZ;
            }
            else
            {
                coldWaterOutLedState = STATE_LED_ON;
            }
        }
    }
exitCaculate:
    if (sys_get_remap_status(WORK_MODE_STS_REG_NO, COOLING_STS_BPOS))
    {
        waterLevelLedState = STATE_LED_FLASH_1HZ;
    }
    else
    {
        waterLevelLedState = STATE_LED_OFF;
    }

    beepState.byte = 0;
    BEEPSHORT      = beepShortCount;
    BEEPLONG       = beepLongCount;
    beepLongCount  = 0;
    beepShortCount = 0;
}

/**
 * @brief
 * @param  outWaterval      My Param doc
 */
static void waterOutOpt(uint8_t outWaterval)
{
    //出水处理
    if (outWaterval == TRUE)
    {
        g_sys.config.ComPara.u16Water_Mode = WATER_NORMAL_ICE;
        g_sys.config.ComPara.u16Water_Flow = 5000;
    }
    else
    {
        g_sys.config.ComPara.u16Water_Mode = 0;
        g_sys.config.ComPara.u16Water_Flow = 0;
    }
}

/**
 * @brief
 * @param  buff             data buff
 * @return rt_uint8_t
 */
static rt_uint8_t dataRepare(rt_uint8_t *buff)
{
    rt_uint8_t *regPoint = RT_NULL;
    rt_memcpy(tx_buffer, protocolHeader, 2);

    if (BLEON && BLEINITDONE)
    {
        regPoint = getRegData();
    }

    if (regPoint)
    {
        buff[2] = CMD_REG_UP;
        buff[3] = 14;
        rt_memcpy(&buff[4], regPoint, 14);
        *(buff + 4 + *(buff + 3)) = getCheckSum(buff);
        goto repareExit;
    }
    if (rt_memcmp(segmentValue, segmentValueBak, 6))
    {
        *(buff + 2) = CMD_SEGMENT;
        *(buff + 3) = 6;
        rt_memcpy(buff + 4, segmentValue, 6);
        *(buff + 4 + *(buff + 3)) = getCheckSum(buff);
        rt_memcpy(segmentValueBak, segmentValue, 6);
        goto repareExit;
    }
    if ((!PARAOK) || rt_memcmp(keyBeepMask, keyBeepMaskBak, 2))
    {
        bleKeyLog("keyBeepMask [0]:%02x [1]:%02x", keyBeepMask[0], keyBeepMask[1]);
        *(buff + 2) = CMD_PARA;
        *(buff + 3) = 2;
        rt_memcpy((buff + 4), keyBeepMask, 2);
        *(buff + 4 + *(buff + 3)) = getCheckSum(buff);
        rt_memcpy(keyBeepMaskBak, keyBeepMask, 2);
        goto repareExit;
    }
    if ((!BOARDRGB) || (rt_memcmp(&levelRGB, &levelRGBBak, sizeof(rgbLevel_t))))
    {
        bleKeyLog("levelRGB [0] [1]");
        *(buff + 2) = CMD_RGBLEVEL;
        *(buff + 3) = sizeof(rgbLevel_t);
        rt_memcpy((buff + 4), &levelRGB, sizeof(rgbLevel_t));
        *(buff + 4 + *(buff + 3)) = getCheckSum(buff);
        rt_memcpy(&levelRGBBak, &levelRGB, sizeof(rgbLevel_t));
        goto repareExit;
    }

    {
        rt_uint8_t len = 0;
        caculateLed();
        *(buff + 2) = CMD_LED;
        *(buff + 3) = 3;
        *(buff + 4) = beepState.byte;
        for (len = 0; len < (*(buff + 3) - 1); len++)
        {
            *(buff + 5 + len) = ledState[len].byte;
        }
        *(buff + 4 + *(buff + 3)) = getCheckSum(buff);
        goto repareExit;
    }

repareExit:
    return (*(buff + 3) + 5);
}
void ledDataInit(void)
{
    levelRGB.level = 0;
    if (g_sys.status.ComSta.u16edition == HOT_COLD_EDITION)
        goto coldEdition;
    HOT_RGB_WATER_SRC.blue  = 50;
    HOT_RGB_WATER_SRC.green = 50;
    HOT_RGB_WATER_SRC.red   = 50;
    HOT_RGB_WATER_OUT.red   = 0;
    HOT_RGB_WATER_OUT.green = 0;
    HOT_RGB_WATER_OUT.blue  = 50;
    HOT_RGB_WATER_HEA.red   = 50;
    HOT_RGB_WATER_HEA.green = 0;
    HOT_RGB_WATER_HEA.blue  = 0;
    return;
coldEdition:
    COLD_RGB_WATER_OUT.blue  = 50;
    COLD_RGB_WATER_OUT.green = 50;
    COLD_RGB_WATER_OUT.red   = 50;
    COLD_RGB_FILTER.red      = 50;
    COLD_RGB_FILTER.green    = 50;
    COLD_RGB_FILTER.blue     = 50;
    COLD_RGB_ELEMENT.red     = 50;
    COLD_RGB_ELEMENT.green   = 50;
    COLD_RGB_ELEMENT.blue    = 50;
}

static void i2c_thread_entry(void *para)
{
    static rt_uint8_t len = 0;
    rt_kprintf("*************start ledkey thread***********\r\n");
    rt_thread_delay(1000);
    ledDataInit();
    while (1)
    {
        /* 调用I2C设备接口传输数据 */
        if (len == 0)
        {
            len = dataRepare(tx_buffer);
        }
        if (i2c_write(I2C_ADDRESS, tx_buffer, 20) == 1)
        {
            len = 0;
        }
        else
        {
            rt_thread_delay(rt_tick_from_millisecond(1000));
            rt_kprintf("i2c_write err \n");
            continue;
        }
        rt_thread_delay(rt_tick_from_millisecond(50));
        if (i2c_read(I2C_ADDRESS, 0, rx_buffer, 20) == 20)
        {
            operateRxData(rx_buffer);
        }
        else
        {
            rt_thread_delay(rt_tick_from_millisecond(1000));
            rt_kprintf("i2c_read err \n");
            // continue;
        }
        rt_thread_delay(rt_tick_from_millisecond(50));
    }
}

int i2cBleThreadInit(void)
{
#ifdef I2C_TOOLS_USE_SW_I2C
    if (i2c_init(SDA_PORT_NUM, SCL_PORT_NUM))
    {
        rt_kprintf("[i2c] failed to find bus with sda=%d scl=%d\n", SDA_PORT_NUM, SCL_PORT_NUM);
        return RT_ERROR;
    }
#else
    char name[RT_NAME_MAX];
    rt_strncpy(name, I2C_DEVICE_NAME, RT_NAME_MAX);
    if (i2c_init(name))
    {
        rt_kprintf("[i2c] failed to find bus %s\n", name);
        return RT_ERROR;
    }

#endif
    /* 创建 i2c 线程 */
    rt_thread_t thread = rt_thread_create("i2c", i2c_thread_entry, RT_NULL, 4096, KEY_THREAD_PRIO, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        rt_kprintf("thread_create i2c err \n");
        return RT_ERROR;
    }
    return RT_EOK;
}
INIT_APP_EXPORT(i2cBleThreadInit);
